package com.zyx.juc.cf.my;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author Yaxi.Zhang
 * @since 2022/12/7 17:41
 */
public class CompletableFutureAllOfDemo4 {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        List<CompletableFuture<String>> cfs = new ArrayList<>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("start job: " + sdf.format(Calendar.getInstance().getTime()));

        for (int i = 1; i < 4; i++) {
            final int j = i;
            CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
                        try {
                            TimeUnit.SECONDS.sleep(j);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // if (j == 1) {
                        //     throw new RuntimeException("bad luck");
                        // }
                        return "job-" + j;
                    })
                    // 完成时的回调函数
                    .whenComplete((s, throwable) -> System.out.println("time: " + sdf.format(Calendar.getInstance().getTime()) + ", task: " + s));
            cfs.add(cf);
        }
        try {
            // get可以指定超时时间
            CompletableFuture.allOf(cfs.toArray(new CompletableFuture[0])).get(4, TimeUnit.SECONDS);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 出现异常后应当手动取消future
            for (CompletableFuture<String> cf : cfs) {
                System.out.println("begin to cancel future: " + cf);
                cf.cancel(true);
            }
        } finally {
            executorService.shutdown();
        }
    }

}
